package com.ruoyi.framework.config.redis.cluster;


import com.ruoyi.framework.config.properties.RedisClusterConfigProperties;
import com.ruoyi.framework.config.redis.cluster.manager.RedisClusterManager;
import com.ruoyi.framework.config.redis.cluster.manager.RedisOperator;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Set;

/**
 * redis-cluster 集群+CacheManager 配置
 */

//@Configuration
public class JedisClusterConfig {

    @Resource
    private RedisClusterConfigProperties clusterProperties;

    @Autowired
    private RedisOperator redisOperator;

    @Bean
    public RedisClusterConfiguration getClusterConfig() {
        RedisClusterConfiguration rcc = new RedisClusterConfiguration(clusterProperties.getClusterNodes());
        rcc.setMaxRedirects(clusterProperties.getClusterMaxRedirects());
        rcc.setPassword(RedisPassword.of(clusterProperties.getPassword()));
        return rcc;
    }

    @Bean
    public JedisCluster getJedisCluster() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(clusterProperties.getPoolMaxIdle());
        poolConfig.setMinIdle(clusterProperties.getPoolMinIdle());
        poolConfig.setMaxWaitMillis(clusterProperties.getPoolMaxWait());
        poolConfig.setMaxTotal(clusterProperties.getPoolMaxActive());

        // 截取集群节点
        String[] cluster = clusterProperties.getClusterNodes().toArray(new String[0]);
        // 创建set集合
        Set<HostAndPort> nodes = new HashSet<HostAndPort>();
        // 循环数组把集群节点添加到set集合中
        for (String node : cluster) {
            String[] host = node.split(":");
            //添加集群节点
            nodes.add(new HostAndPort(host[0], Integer.parseInt(host[1])));
        }
        return new JedisCluster(nodes, clusterProperties.getRedisTimeout(), 1000, 1, clusterProperties.getPassword(), poolConfig);
    }


    @Bean
    public JedisConnectionFactory redisConnectionFactory(RedisClusterConfiguration cluster) {
        return new JedisConnectionFactory(cluster);
    }

    /**
     * 缓存管理器
     * @param connectionFactory
     * @return
     */
    @Bean
    public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheManager cacheManager = new RedisCacheManager();
        cacheManager.setRedisManager(redisManager());
        return cacheManager;
    }

    @Bean
    public RedisManager redisManager() {
        RedisClusterManager redisManager = new RedisClusterManager();
        redisManager.setJedisCluster(getJedisCluster());
        redisManager.setRedisOperator(redisOperator);
        redisManager.setExpire(3600); //设置缓存时间 单位：s
        return redisManager;
    }

}
